clojure.core の数値に関する var
整数は java.lang.Long、小数は java.lang.Double で生成される
code:clj
(type 1) ; java.lang.Long
(type 1.0) ; java.lang.Double
末尾に M と N を付けると、それぞれ clojure.lang.BigInt と java.math.BigDecimal で生成される
code:clj
(type 1N) ; clojure.lang.BigInt
(type 1M) ; java.math.BigDecimal
非数、正 / 負の無限大は ##NaN、##Inf、##-Inf で表し、java.long.Double で生成される
code:clj
(type ##NaN) ; java.lang.Double
(type ##Inf) ; java.lang.Double
(type ##-Inf) ; java.lang.Double
long の最大値を超える整数を記述すると、clojure.long.BigInt で生成される
code:clj
Long/MAX_VALUE ; 9223372036854775807
(type 9223372036854775807) ; java.lang.Long
(type 9223372036854775808) ; clojure.lang.BigInt
リテラルの整数では 基数 を指定できる
2 進数: 2r、8 進数: 0、16 進数: 0x、32 進数: 36r
code:clj
2r101 017 0x1f 36rCRAZY ; 5 15 31 21429358
基数を指定しつつ、clojure.lang.BigInt を生成することも可能
code:clj
(type 0x1fN) ; clojure.lang.BigInt
キャスト用の関数が用意されているため、それぞれの型に変換が可能
byte: java.lang.Byte へ変換
short: java.lang.Short へ変換
int: java.lang.Int へ変換
long: java.lang.Long へ変換
bigint: clojure.lang.BigInt へ変換
末尾 N のリテラルで生成されるインスタンスと同じ
java.math.BigInteger と比べてパフォーマンスが高い
e.g. java.lang.Double で十分な場合は Double で確保する
biginteger: java.math.BigInteger へ変換
float: java.lang.Float へ変換
double: java.lang.Double へ変換
bigdec: java.math.BigDecimal へ変換
code:clj
(map #(-> 42 % type) byte short int long bigint biginteger float double bigdec)
;; (java.lang.Byte
;; java.lang.Short
;; java.lang.Integer
;; java.lang.Long
;; clojure.lang.BigInt
;; java.math.BigInteger
;; java.lang.Float
;; java.lang.Double
;; java.math.BigDecimal)
num: java.lang.Number へ変換
主に型チェックに用いられる
code:clj
(map (comp type num) 42 42N 3.14 3.14M 1/3)
;; (java.lang.Long
;; clojure.lang.BigInt
;; java.lang.Double
;; java.math.BigDecimal
;; clojure.lang.Ratio)
述語関数
int?: 引数が 固定精度整数 か(e.g. java.lang.Long)
integer?: 引数が整数か
float?: 引数が 浮動小数点数 か
decimal?: 引数が java.math.BigDecimal か
number?: 引数が java.lang.Number か
文字列(java.lang.String)から数値への変換
parse-long: 文字列を java.lang.Long に変換する
code:clj
(type (parse-long "42")) ; java.lang.Long
parse-double: 文字列を java.lang.Double に変換する
code:clj
(type (parse-double "42")) ; java.lang.Double
どちらも、変換できない場合は nil を返す
code:clj
(parse-long "abc") ; nil
(parse-double "abc") ; nil
数値の判定
数直線 関連(数値が数直線上でどこに位置しているか)
zero?: 引数が 0 か
pos?: 引数が正の数か
neg?: 引数が負の数か
code:clj
(map (juxt neg? zero? pos?) -1.0 0.0 -0.0 1 1.2)
;; (true false false
;; false true false
;; false true false
;; false false true
;; false false true)
NaN?: 引数が ##NaN か
infinite?: 引数が ##Inf または ##-Inf か
code:clj
(map (juxt NaN? infinite?) 1.0 ##NaN ##Inf ##-Inf)
;; (false false
;; true false
;; false true
;; false true)
上記はすべて、数値ではない値を渡すとエラーを吐く(ClassCastException)
整数関連
even?: 引数が奇数か
odd?: 引数が偶数か
code:clj
(map (juxt even? odd?) -2 -1 0 1 2)
;; (true false false true true false false true true false)
pos-int?: 引数が正の固定精度整数か
neg-int?: 引数が負の固定精度整数か
nat-int?: 引数が 0 または正の固定精度整数か
code:clj
map (juxt neg-int? pos-int? nat-int?) -1 0 1 1.2)
;; (true false false
;; false false true
;; false true true
;; false false false)
数値比較
<, <=, ==, >, >=: 引数を java.lang.Number に変換して数値比較する
code:clj
(map
#(map (partial apply %)
[1 2
1 2 3
1 2 2
2 2
2 2 1
3 2 1
2 1])
<= == >= >)
;; ((true true false false false false false)
;; (true true true true false false false)
;; (false false false true false false false)
;; (false false false true true true true)
;; (false false false false false true true))
数値以外を渡すとエラーを吐く(ClassCastException)
code:clj
(< "a" "b")
ただし、引数が 1 つの場合は 最適化 により必ず true を返す
code:clj
[(< 1)
(<= 1)
(== 1)
(>= 1)
(> 1)]
;; true true true true true
[(< "a")
(<= "a")
(== "a")
(>= "a")
(> "a")]
;; true true true true true
四則演算
+, *: 加算と乗算
可変長引数を受け取り、それぞれ演算を行う
引数がない場合、単位元 である 0 と 1 を返す
code:clj
(+) ; 0
(*) ; 1
引数がある場合、単位元に対して引数に対する演算を行う
code:clj
(+ 2) ; 2
(+ 2 3 4) ; 9
(* 2) ; 2
(* 2 3 4) ; 24
-、/: 減算と除算
引数が 1 つの場合、その値に対して 単項演算 を行う
code:clj
(- 2) ; -2
(/ 2) ; 1/2
引数が 2 つ以上の場合、1 つ目の引数に対して順に演算を行う
code:clj
(- 10 2 3) ; 5
(/ 10 2 3) ; 5/3
+ と *、- は、Long の引数に対して オーバーフロー する演算を行うとエラーを吐く(ArithmeticException)
code:clj
(+ Long/MAX_VALUE 1)
代わりに +' と *'、-' を用いると Auto promote を行うので、エラーが起きない
code:clj
(+' Long/MAX_VALUE 1) ; 9223372036854775808N
quot: 除算の商を返す
code:clj
(quot 10 3) ; 3
rem: 除算の余剰を返すが、被除数の符号と一致する結果を返す
code:clj
(rem -10 3) ; -1
(rem 10 -3) ; 1
mod: 除算の余剰を返すが、除数の符号と一致する結果を返す
code:clj
(mod -10 3) ; 2
(mod 10 -3) ; -2
inc / dec: インクリメント / デクリメント
code:clj
(map (juxt inc dec) 1 2 3 1/2 1.5)
;; (2 0 3 1 4 2 3/2 -1/2 2.5 0.5)
Long の引数に対して オーバーフロー する演算を行うとエラーを吐くため、代わりに inc' と dec' が使える
code:clj
(inc' Long/MAX_VALUE) ; 9223372036854775808N
abs: 絶対値 を返す
code:clj
(map abs -1 0 1) ; (1 0 1)
Long/MIN_VALUE を渡した場合、その値をそのまま返す
code:clj
(abs Long/MIN_VALUE) ; -9223372036854775808
#Clojure